package com.wsm.kotlintest.model.datafactory

import androidx.lifecycle.MutableLiveData
import androidx.paging.PageKeyedDataSource
import com.wsm.kotlintest.common.*
import com.wsm.kotlintest.model.datamodel.BaseModel
import com.wsm.kotlintest.model.response.BaseResponseModel
import com.wsm.kotlintest.model.response.redditResponseModel.Children
import com.wsm.kotlintest.viewmodel.ui.DataResponseCallBack
import com.wsm.kotlintest.viewmodel.ui.NetStateCallBack
import io.reactivex.Observable

/**
 * Created by 王家宝 on 2018/7/24.
 * TEL:18241150668
 * MAIL:639586819@qq.com
 */

enum class Type {
    INIT,
    NEXT,
}

abstract class BaseDataSource<Key, Value>(
        var netState: MutableLiveData<Boolean>,
        var refreshing: MutableLiveData<Boolean>,
        var loadMoreState: MutableLiveData<Int>) : PageKeyedDataSource<Key, Value>() {

    abstract var dataModel: BaseModel

    var retryCallback: (() -> Any)? = null

    fun retryWhenLoadMore() {
        retryCallback?.invoke()
    }

    override fun loadInitial(params: LoadInitialParams<Key>, callback: LoadInitialCallback<Key, Value>) {
        loadMoreState.postValue(LOAD_MORE_STATE_DEFAULT)
        kotlin.run {
            netState.postValue(true)
        }
        init(params, callback)
    }

    override fun loadAfter(params: LoadParams<Key>, callback: LoadCallback<Key, Value>) {
        retryCallback = { loadAfter(params, callback) }
        loadMoreState.postValue(LOAD_MORE_STATE_LOADING)
        onNext(params, callback)
    }

    override fun loadBefore(params: LoadParams<Key>, callback: LoadCallback<Key, Value>) {
    }

    abstract fun init(params: LoadInitialParams<Key>, callback: LoadInitialCallback<Key, Value>)
    abstract fun onNext(params: LoadParams<Key>, callback: LoadCallback<Key, Value>)

    fun <T> requestApi(api: Observable<BaseResponseModel<T>>, finalCallBack: DataResponseCallBack<T>, type: Type = Type.INIT) {
        dataModel.getData(api, callback = object : NetStateCallBack<T> {
            override fun onDataResponse(data: T) {
                when (type) {
                    Type.INIT -> {
                        netState.value = true
                        refreshing.value = false
                    }
                    Type.NEXT -> {
                        netState.value = true
                        refreshing.value = false
                        retryCallback = null
                    }
                }
                finalCallBack.finalResponse(data)
            }

            override fun onDataError() {
                when (type) {
                    Type.INIT -> {
                        refreshing.value = false
                        loadMoreState.value = LOAD_MORE_STATE_DEFAULT
                    }
                    Type.NEXT -> {
                        refreshing.value = false
                        loadMoreState.value = LOAD_MORE_STATE_ERROR
                    }
                }

            }

            override fun onNetNotAvailable() {
                when (type) {
                    Type.INIT -> {
                        netState.postValue(false)
                        refreshing.postValue(false)
                        loadMoreState.postValue(LOAD_MORE_STATE_DEFAULT)
                    }
                    Type.NEXT -> {
                        refreshing.postValue(false)
                        loadMoreState.postValue(LOAD_MORE_STATE_ERROR)
                    }

                }

            }

        })
    }


}